package com.lnj.messages.consumer;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lnj.bean.model.Usercoupon;
import com.lnj.bean.vo.CouponMessage;
import com.lnj.messages.mapper.CouponMapper;
import com.lnj.messages.mapper.UsercouponMapper;
import com.lnj.messages.utiles.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class CouponConsumer {
    @Autowired
    private JsonUtil jsonUtil;
    @Autowired
    private CouponMapper couponMapper;
    @Autowired
    private UsercouponMapper usercouponMapper;
    @Autowired
    private RedissonClient redissonClient;

    @KafkaListener(topics = "coupon")
    @Transactional
    public void consume(String message){
        CouponMessage couponMessage = jsonUtil.fromJson(message, CouponMessage.class);
        log.info("优惠券消息:{}",couponMessage);
        String lockKey = "coupon:lock:" + couponMessage.getUserId() + ":" + couponMessage.getCouponId();
        RLock lock = redissonClient.getLock(lockKey);
        try {
            if (lock.tryLock(3, 10, TimeUnit.SECONDS)) {
                // 检查是否已处理过
                if (checkUserCoupon(couponMessage.getUserId(), couponMessage.getCouponId(),couponMessage.getCreateTime())) {
                    log.warn("重复消费: {}", message);
                    return;
                }

                // 扣减数据库库存
                if (couponMapper.reduceStock(couponMessage.getCouponId()) <= 0) {
                    log.error("Stock reduce failed: {}", message);
                    return;
                }

                // 创建用户优惠券
                Usercoupon userCoupon = new Usercoupon();
                userCoupon.setUserId(couponMessage.getUserId());
                userCoupon.setCouponId(couponMessage.getCouponId());
                userCoupon.setStatus((byte) 0);
                userCoupon.setGetTime(couponMessage.getCreateTime());
                usercouponMapper.insert(userCoupon);

                log.info("处理成功: {}", message);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } catch (Exception e) {
            log.error("处理优惠券异常: {}", message, e);
            // 异常处理：记录失败日志，后续人工补偿
        } finally {
            lock.unlock();
        }
    }

    private boolean checkUserCoupon(Long userId, Long couponId, LocalDateTime createTime) {
        Long count = usercouponMapper.selectCount(new LambdaQueryWrapper<Usercoupon>()
                .eq(Usercoupon::getUserId, userId)
                .eq(Usercoupon::getCouponId, couponId)
                .eq(Usercoupon::getStatus,0)
                .eq(Usercoupon::getGetTime, createTime));
        return count > 0;
    }
}
